#include "collection.h"
#include "data.h"


#include <QDebug>
#include <QTimer>


Collection::Collection(QObject *parent) :
    AbstractData(parent),
    d(new Data())
{
    QTimer::singleShot(0, this, SLOT(resolveRefs()));
}


Collection::Collection(const QString &name, QObject *parent) :
    AbstractData(parent),
    d(new Data())
{
    setName(name);
    QTimer::singleShot(0, this, SLOT(resolveRefs()));
}

Collection::Collection(const Collection &other) :
    AbstractData(other),
    d(other.d)
{
    setName(other.name());
}


QString Collection::name() const
{
    return d->name;
}

void Collection::setName(const QString &name)
{
    if (d->name == name) return;

    d->name = name;

    setObjectName(d->name);

    emit sigChanged();
}

void Collection::addField(const QString &fieldName)
{
    MetaDataPtr meta = metaData();
    if (meta.isNull()) meta = new MetaData(this);

    meta->addItem(fieldName);
}

void Collection::setField(int index, const QString &fieldName, bool editable)
{
    MetaData* meta = metaData();
    if (!meta) meta = new MetaData(this);

    MetaItem* metaItem = meta->item(index);
    if (!metaItem)
    {
        meta->insertItem(index, fieldName);
        metaItem = meta->item(index);
    }
    else
    {
        metaItem->setField(fieldName);
    }

    if (!metaItem) return;

    metaItem->setEditable(editable);
}

void Collection::removeField(int index)
{
    MetaDataPtr meta = metaData();
    if (meta.isNull()) return;

    meta->removeItem(index);
}

QStringList Collection::fields() const
{
    MetaDataPtr meta = metaData();
    if (meta.isNull()) return QStringList();

    QStringList ret;
    foreach (MetaItem* item, meta->findChildren<MetaItem*>())
    {
        if (!item) continue;

        ret << item->field();
    }

    return ret;
}


QVariant Collection::value(int field, int role) const
{
    if (role != Qt::DisplayRole) return QVariant();
    if (field) return QVariant();

    return name();
}

void Collection::setValue(int field, const QVariant &value)
{
    if (field) return;

    setName(value.toString());
}


QStringList Collection::options(int field) const
{
    Collection* refParent = 0;
    if (!d->optionRefs.contains(field))
    {
        return QStringList();
    }

    refParent = d->optionRefs.value(field);


    QStringList ret;
    foreach (QObject* obj, refParent->children())
    {
        Item* item = qobject_cast<Item*>(obj);
        if (!item) continue;

        ret << item->value(0).toString();
    }

    return ret;
}


MetaData *Collection::metaData() const
{
    if (!d->meta.isNull())
    {
        return d->meta;
    }

    MetaData* meta = findChild<MetaData*>();
    if (meta && meta->parent() != this) return 0;

    return meta;
}

void Collection::resolveRefs()
{
    MetaData* meta = metaData();
    if (!meta)
    {
        return;
    }

    d->meta = meta;

    foreach (MetaItem* metaItem, meta->items())
    {
        if (!metaItem) continue;
        QString refName = metaItem->optionRef();

        if (refName.isEmpty()) continue;

        Collection* refParent = root()->findChild<Collection*>(refName);
        if (!refParent) continue;

        int field = metaItem->index();
        d->optionRefs.insert(field, refParent);
    }


}

